Caching sémantique pour LLMs : réduire latence et coûts d’inférence sans sacrifier la pertinence

Dans tout chatbot ou assistant LLM à volumétrie élevée, une proportion importante des requêtes utilisateur sont sémantiquement équivalentes à des requêtes déjà traitées. « Comment réinitialiser mon mot de passe ? », « j’ai oublié mon pass », « mdp perdu, besoin d’aide » : trois formulations, une seule intention, une seule réponse pertinente. Le caching sémantique capitalise sur cette redondance en servant la réponse déjà calculée pour des requêtes jugées assez proches sémantiquement de requêtes passées. Correctement calibré, il réduit la latence de 2 à 3 ordres de grandeur sur les hits et divise les coûts d’inférence d’un facteur significatif. Mal calibré, il sert des réponses hors-sujet et dégrade l’expérience utilisateur. L’enjeu technique est la calibration du seuil de similarité. LLMOps : guide complet pour déployer et opérer un LLM en production

À retenir en 30 secondes : le caching sémantique calcule l’embedding de chaque requête entrante, cherche dans un cache les requêtes passées dont la similarité cosinus dépasse un seuil, et renvoie leur réponse si trouvées. La performance dépend de trois paramètres : le modèle d’embedding utilisé, le seuil de similarité, et la politique d’invalidation. Les gains typiques en production : hit ratio de 15 à 40 % sur un workload chatbot grand public, latence du hit sous 50 ms, économie API de 20 à 50 % sur la facture mensuelle.

Différence fondamentale avec le prompt caching

Il est essentiel de distinguer le caching sémantique du prompt caching exposé par les API, les deux étant complémentaires mais opérant à des couches distinctes. Le prompt caching du fournisseur réutilise les KV caches internes pour un préfixe exactement identique : il économise sur la phase de prefill mais le modèle génère toujours la réponse. Le caching sémantique, lui, intercepte la requête avant même l’appel à l’API et renvoie une réponse pré-calculée pour une requête sémantiquement proche. L’économie est totale (zéro token facturé, zéro latence d’inférence), mais au prix d’un risque qualitatif qu’il faut maîtriser.

Architecture technique d’un cache sémantique

Les composants d’une implémentation production sont au nombre de cinq. Un modèle d’embedding léger et rapide (text-embedding-3-small, bge-small, all-MiniLM) qui transforme chaque requête en vecteur de 384 à 1536 dimensions. Une base vectorielle dédiée au cache (Qdrant, Redis Stack, pgvector sont tous adaptés). Un index de recherche par similarité cosinus avec seuil configurable. Une politique de rétention (TTL par entrée, LRU, taille maximale). Un mécanisme d’invalidation explicite (quand un contenu référencé change, les entrées correspondantes doivent être purgées).

Le flux est le suivant à chaque requête : (1) embedding de la requête, (2) recherche dans le cache des K plus proches voisins, (3) si le meilleur voisin dépasse le seuil, retourner sa réponse pré-calculée, (4) sinon appeler le LLM, (5) stocker la paire (requête, réponse) dans le cache avec son embedding. Le pattern est simple ; le diable est dans la calibration.

Calibrer le seuil de similarité : la clé opérationnelle

Un seuil trop élevé (par exemple 0.95) rend le cache quasi inutile : seules les requêtes quasi identiques matchent, le hit ratio reste faible. Un seuil trop bas (par exemple 0.75) sert des réponses hors contexte, dégradant l’UX. La bonne pratique consiste à calibrer sur un jeu de données annoté manuellement : prendre 500 à 1000 paires de requêtes réelles de production, annoter « équivalentes » ou « différentes », et ajuster le seuil pour maximiser la précision tout en préservant un rappel acceptable. Le seuil optimal se situe typiquement entre 0.85 et 0.92 selon le modèle d’embedding et le domaine métier. Long-context LLMs : techniques et limites pour exploiter réellement 1 million de tokens en production

Les équipes matures ajoutent une seconde ligne de défense : un classifieur léger qui filtre les faux positifs potentiels avant de servir le hit, ou un re-prompt du LLM uniquement pour valider que la réponse cachée reste pertinente. Cette architecture hybride préserve l’économie massive du cache tout en limitant le risque qualitatif. L’approche est à rapprocher du pattern de reranking qu’on utilise sur un RAG en production.

Politiques d’invalidation et gestion de la fraîcheur

La question de la fraîcheur est centrale pour tout cache. Trois mécanismes se combinent en production. Le TTL par entrée (24h à 7 jours selon le domaine) garantit que le cache ne vieillit pas indéfiniment. L’invalidation explicite par tag permet de purger toutes les entrées liées à un contenu modifié (par exemple : toutes les requêtes sur la politique de retour quand la politique change). La détection d’anomalies de drift peut déclencher une purge globale si une proportion anormale des hits sont ensuite marqués pertinents à faux positif. L’absence d’invalidation est l’erreur la plus courante : un cache qui sert des réponses obsolètes sur une base périmée est pire que pas de cache du tout.

Cas d’usage où le caching sémantique est contre-indiqué

Trois contextes rendent le caching sémantique inadapté. Les applications conversationnelles multi-tour avec historique : la réponse à « et pour la deuxième option ? » dépend du contexte précédent, pas de la seule requête courante. Les applications personnalisées où la réponse dépend fortement de l’utilisateur (profil, historique, préférences) : deux requêtes identiques peuvent légitimement produire deux réponses différentes. Les cas sensibles au risque qualitatif (santé, finance, juridique) où un faux positif de similarité peut avoir des conséquences graves. Dans ces contextes, un cache exact (sur requête littéralement identique) reste pertinent mais le cache sémantique est trop risqué.

Pour une mise en œuvre pratique, la bibliothèque open source GPTCache offre une implémentation prête à l’emploi, intégrable derrière la plupart des frameworks LLM. Elle est également un bon support pédagogique pour comprendre les mécaniques internes.

Mon point de vue d’expert

Le caching sémantique est l’une des optimisations les plus rentables sur un chatbot grand public à fort trafic, mais aussi l’une des plus dangereuses à mettre en œuvre sans discipline. Je conseille toujours trois choses aux équipes françaises que je conseille : (1) démarrer avec un seuil conservateur (0.92) et le baisser progressivement en mesurant la qualité ; (2) ne jamais déployer un cache sémantique sans dashboard de hit ratio et sans un pipeline d’évaluation continue sur un échantillon des hits ; (3) exclure explicitement du cache les intents sensibles au risque (toute requête contenant un montant, une donnée nominative, un mot-clé juridique). Avec cette discipline, l’économie est réelle et saine ; sans elle, c’est un piège qui finit par coûter plus cher en incidents client qu’en facture API économisée. KV cache management : la clé pour maîtriser la mémoire GPU dans les déploiements LLM à grande échelle

FAQ : caching sémantique en production

Quel modèle d’embedding utiliser pour le cache ?
Privilégier un modèle rapide et peu coûteux : text-embedding-3-small (OpenAI), bge-small-en-v1.5 ou all-MiniLM-L6-v2 (open source) sont des choix solides. L’important est que le temps de calcul de l’embedding reste très inférieur à la latence de l’appel LLM (idéalement sous 30 ms). Un modèle lourd annule le gain.
Quel hit ratio viser en production ?
Entre 15 et 40 % sur un chatbot grand public typique, selon la diversité réelle des intents. Un hit ratio trop élevé (plus de 60 %) peut révéler un seuil trop permissif, à vérifier par audit qualitatif des hits.
Peut-on cacher les réponses d’un LLM qui génère du contenu créatif ?
Non, c’est contre-productif : la valeur attendue de ces applications est précisément la variété des réponses. Deux utilisateurs qui demandent « écris-moi un poème sur l’automne » doivent recevoir deux poèmes différents, pas le même. Le caching sémantique est pertinent sur les applications informationnelles ou utilitaires, pas sur les applications génératives créatives.
Y a-t-il un enjeu RGPD au stockage des requêtes utilisateur dans le cache ?
Oui, si les requêtes contiennent des données personnelles. Les requêtes stockées (texte + embedding + réponse) deviennent un traitement de données à documenter : base légale, durée de rétention, procédure d’effacement, mesures de sécurité. En pratique, concevoir un cache qui exclut automatiquement les requêtes contenant des éléments identifiants (via détection de PII) est la pratique recommandée pour les applications grand public françaises.